{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import cv2\n",
    "import numpy as np\n",
    "from cv2_common import im_mul_show,im_show\n",
    "# !%run cv2_common.py"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 创建显示OpenCV图片方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "    显示图片\n",
      "    :param img:图片数据\n",
      "    :param name:窗口名称\n",
      "    \n"
     ]
    }
   ],
   "source": [
    "print(im_show.__doc__)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "img = cv2.imread('./image/test.jpg') #从本地加载图片信息\n",
    "# img = cv2.imread('./image/test_02.jpg') #从本地加载图片信息"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "img = cv2.resize(img,None, fx=0.3, fy=0.3, interpolation=cv2.INTER_AREA) # 按比例缩放图片\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "im_show(cv2.resize(img,(300,200), interpolation=cv2.INTER_AREA) ) #指定宽高缩放图片"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [],
   "source": [
    "im_mul_show(name=img)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cv2.imwrite('./image/test_02.jpg',new_img)  #保存图片"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "im_show(cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)) # 颜色转换"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 高斯模糊 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "gb7 = cv2.GaussianBlur(img,(7,7),sigmaX=2)\n",
    "gb5 = cv2.GaussianBlur(img,(5,5),sigmaX=2)\n",
    "gb3 = cv2.GaussianBlur(img,(3,3),sigmaX=2)\n",
    "# targe3 = cv2.GaussianBlur(img,(7,7),sigmaX=50)\n",
    "\n",
    "im_mul_show(orin=img,gb3=gb3,gb5=gb5,gb7=gb7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "im_show(np.hstack([img,targe,targe1,targe2]),\"gaussian\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2024-04-22 23:01:08.511 Python[601:5828] IMKClient Stall detected, *please Report* your user scenario attaching a spindump (or sysdiagnose) that captures the problem - (imkxpc_selectedRangeWithReply:) block performed very slowly (103.23 secs).\n"
     ]
    }
   ],
   "source": [
    "gb7 = cv2.GaussianBlur(img,(3,3),sigmaX=2)\n",
    "gb5 = cv2.GaussianBlur(img,(3,3),sigmaX=20)\n",
    "gb3 = cv2.GaussianBlur(img,(3,3),sigmaX=200)\n",
    "\n",
    "im_mul_show(orin=img,gb3=gb3,gb5=gb5,gb7=gb7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "im_show(np.hstack([img,targe,targe1,targe2]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 中值滤波 去除椒盐噪点效果明显"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [],
   "source": [
    "mb3 = cv2.medianBlur(img,3)\n",
    "mb5 = cv2.medianBlur(img,5)\n",
    "mb7 = cv2.medianBlur(img,7)\n",
    "\n",
    "# im_show(np.hstack([img,targe,targe1,targe2]))\n",
    "im_mul_show(orin=img,mb3=mb3,mb5=mb5,mb7=mb7)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 双边滤波 能够保留图像边缘信息的滤波算法之一,使用双边滤波会具有美颜效果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [],
   "source": [
    "#sigmaColor：颜色空间滤波器的标准差值，这个参数越大表明该像素领域内有越多的颜色被混合到一起，产生较大的半相等颜色区域\n",
    "#sigmaSpace：空间坐标中滤波器的标准差值，这个参数越大表明越远的像素会相互影响，从而使更大领域中有足够相似的颜色获取相同的颜色。\n",
    "#当第三个参数d大于0时，邻域范围由d确定，当第三个参数小于等于0时，邻域范围正比于这个参数的数值。\n",
    "#borderType：像素外推法选择标志，取值范围在表3-5中给出，默认参数为BORDER_DEFAULT，表示不包含边界值倒序填充。\n",
    "bf3 = cv2.bilateralFilter(img,3,sigmaColor=5,sigmaSpace=75) \n",
    "bf5 = cv2.bilateralFilter(img,5,sigmaColor=75,sigmaSpace=75)\n",
    "bf7 = cv2.bilateralFilter(img,7,sigmaColor=75,sigmaSpace=75)\n",
    "\n",
    "#im_show(np.hstack([img,targe,targe1,targe2]))\n",
    "im_mul_show(orin=img,bf3=bf3,bf5=bf5,bf7=bf7)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Sobel 算子 ,边缘检测，需要水平和垂直分别检测最后合成"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [],
   "source": [
    "grey_img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)\n",
    "dx_sobel  = cv2.Sobel(grey_img,cv2.CV_64F,1,0,ksize=3) # 水平边缘信息\n",
    "dy_sobel  = cv2.Sobel(grey_img,cv2.CV_64F,0,1,ksize=3) # 垂直边缘信息\n",
    "target_sobel = cv2.addWeighted(dx_sobel,0.5,dy_sobel,0,5)\n",
    "#targe3= cv2.convertScaleAbs(targe2)\n",
    "\n",
    "#im_show(np.hstack([grey_img,target_sobel]))\n",
    "im_mul_show(grey=grey_img,dx=dx_sobel,dy=dy_sobel,target=target_sobel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Scharr 算子，它是Sobel算子的改进版本，旨在提供更加准确和敏感的边缘检测"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [],
   "source": [
    "grey_img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)\n",
    "dx_scharr = cv2.Scharr(grey_img,cv2.CV_64F,1,0) # 水平边缘信息\n",
    "dy_scharr = cv2.Scharr(grey_img,cv2.CV_64F,0,1) # 垂直边缘信息\n",
    "target_scharr = cv2.addWeighted(dx_scharr,0.5,dy_scharr,0,5)\n",
    "# target_scharr= cv2.convertScaleAbs(target_scharr)\n",
    "\n",
    "#im_show(np.hstack([grey_img,target_scharr,targe_sobel]))\n",
    "\n",
    "im_mul_show(grey=grey_img,dx=dx_scharr,dy=dy_scharr,target=target_scharr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [],
   "source": [
    "grey_img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)\n",
    "dx_scharr = cv2.Scharr(grey_img,cv2.CV_16S,1,0) # 水平边缘信息  # 使用CV_16S会有负值出现，需要使用convertScaleAbs转成正数，gimj\n",
    "dy_scharr = cv2.Scharr(grey_img,cv2.CV_16S,0,1) # 垂直边缘信息\n",
    "target_scharr = cv2.addWeighted(dx_scharr,0.5,dy_scharr,0,5)\n",
    "target_scharr= cv2.convertScaleAbs(target_scharr)\n",
    "\n",
    "#im_show(np.hstack([grey_img,target_scharr,targe_sobel]))\n",
    "\n",
    "im_mul_show(grey=grey_img,dx=cv2.convertScaleAbs(dx_scharr),dy=cv2.convertScaleAbs(dy_scharr),target=target_scharr)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 拉普拉斯 算子 Laplacian算子具有各方向同性的特点，能够对任意方向的边缘进行提取，具有无方向性的优点，因此使用Laplacian算子提取边缘不需要分别检测X方向的边缘和Y方向的边缘，只需要一次边缘检测即可。Laplacian算子是一种二阶导数算子，对噪声比较敏感，因此常需要配合高斯滤波一起使用。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [],
   "source": [
    "grey_img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)\n",
    "laplacian = cv2.Laplacian(grey_img, cv2.CV_64F,3)\n",
    "laplacian_scale = cv2.convertScaleAbs(laplacian)\n",
    "#im_show(np.vstack([laplacian,laplacian_scale]))\n",
    "\n",
    "im_mul_show(grey=grey_img,laplacian=laplacian,laplacian_scale=laplacian_scale)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [],
   "source": [
    "grey_img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)\n",
    "laplacian = cv2.Laplacian(grey_img, cv2.CV_16S,3) # 使用CV_16S会有负值出现，需要使用convertScaleAbs转成正数，gimj\n",
    "laplacianAbs = cv2.convertScaleAbs(laplacian)\n",
    "# im_show(np.hstack([grey_img,laplacian]))\n",
    "im_mul_show(grey=grey_img,laplacian=laplacian,laplacianAbs=laplacianAbs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
